<template>
  <el-card class="map-plugin-container">
    <div class="map-container">
      <div class="map-header">
        <h3>
          访问地区<br>
          <span class="province" v-if="mapData.mapSelect === 'chinaMap'">TOP 10省份</span>
          <span class="country" v-if="mapData.mapSelect === 'worldMap'">TOP 10国家</span>
        </h3>
        <el-button size="mini" type="primary" @click="toggleMap">
          切换为{{ mapData.btnText }}
        </el-button>
      </div>
      <el-row :gutter="40" class="map-content">
        <el-col :span="10">
          <div class="map-msg-list">
            <div class="map-msg-item" v-for="(item,i) in mapData.topTenArea" :key="item">
              <span class="map-msg-name">{{ i + 1 }}.{{ item.name }}</span>
              <span class="map-msg-percent">{{ item.percent }}%</span>
              <span class="map-msg-count">{{ item.value }}次</span>
            </div>
          </div>
        </el-col>
        <el-col :span="14">
          <div ref="mapRef" id="map" style="width:100%;height: 100%"></div>
        </el-col>
      </el-row>
    </div>
  </el-card>
</template>

<script setup>
import { getCurrentInstance, onMounted, reactive } from 'vue'
import '@/assets/maps/china.js'
import '@/assets/maps/world.js'
import nameMap from '@/assets/maps/nameMap'
const { proxy } = getCurrentInstance()

let mapCharts = null
onMounted(()=>{
  mapCharts = proxy.$echarts.init(proxy.$refs.mapRef)
  mapCharts.setOption(option)
  window.onresize = ()=>mapCharts.resize()
})

const mapData = reactive({
  // 地图切换按钮。chinaMap为中国地图,worldMap为世界地图
  mapSelect: 'chinaMap',
  btnText: '世界地图',
  topTenArea: [],
  accessTotal: null,
})

let areaList = ['南海诸岛', '北京', '天津', '上海', '重庆', '河北', '河南', '云南', '辽宁', '黑龙江', '湖南', '安徽', '山东', '新疆', '江苏', '浙江', '江西', '湖北', '广西', '甘肃', '山西', '内蒙古', '陕西', '吉林', '福建', '贵州', '广东', '青海', '西藏', '四川', '宁夏', '海南', '台湾', '香港', '澳门']

const cutTopTen = data=>{
  mapData.topTenArea = data
  let unKnowCount = mapData.accessTotal
  data.forEach(item => unKnowCount -= item.value)
  mapData.topTenArea.push({
    value: unKnowCount,
    name: mapData.mapSelect === 'chinaMap' ? '国外和未知' : '未知',
    percent: (unKnowCount / mapData.accessTotal * 100).toFixed(2)
  })
  mapData.topTenArea = mapData.topTenArea.sort((a,b) => b.value - a.value).filter(item=> item.value > 0).slice(0,10)
}

let option = {
  tooltip: {
    show: true,
    extraCssText:'background-color:rgba(0,0,0,.6);color:#fff;',
    formatter:function(params,ticket, callback){
      return `${params.data.name} ${params.data.value}次`
    }//数据格式化
  },
  //左侧小导航图标
  visualMap: {
    show : true,
    type:'continuous',
    x: 'right',
    y: 'bottom',
    min:0,
    calculable:false,
    color: ['rgb(0,95,255)','rgb(236,236,236)'] //数据颜色
  },
  series:[{
    name: '数据',
    type: 'map',
    mapType: 'china',
    zoom: 1.2,
    roam: false,
    select:{
      label:{
        show:false
      },
      itemStyle:{
        areaColor: 'rgb(236,236,236)', //背景颜色
      }
    },
    label: {
      normal: {
        show: false, //关闭名称展示
        fontSize: '14',
      },
      emphasis: {
        show: false
      }
    },
    itemStyle: {
      normal: {
        areaColor: 'rgb(236,236,236)', //背景颜色
        borderColor: '#f8f8f8',
        borderWidth: 1.6,
      },
      emphasis: {
        areaColor: 'rgb(120,223,252)', //hover颜色
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        shadowBlur: 0,
        borderWidth: 0,
      }
    },
    data: []  //数据
  }]
}

const resetMap = ()=>{
  mapCharts.clear()
  mapData.mapSelect === 'chinaMap' ? cutTopTen(chinaData) : cutTopTen(worldData)
  mapCharts.setOption(option)
}

// 切换地图
const toggleMap = ()=>{
  if(mapData.mapSelect === 'chinaMap'){
    mapData.btnText = '中国地图'
    mapData.mapSelect = 'worldMap'
    option.series[0].mapType = 'world'
    option.series[0].nameMap = nameMap
    option.series[0].data = worldData
    resetMap()
  }else if(mapData.mapSelect === 'worldMap'){
    mapData.btnText = '世界地图'
    mapData.mapSelect = 'chinaMap'
    option.series[0].mapType = 'china'
    option.series[0].nameMap = undefined
    option.series[0].data = chinaData
    resetMap()
  }
}

const chartResize = ()=>mapCharts.resize()
let chinaData = reactive(areaList.map(item=>{return { name:item,value:0, percent:0 }}))
let worldData = reactive(Object.values(nameMap).map(item=>{return { name:item, value:0, percent:0 }}))

const chartOption = (data,country_data,count)=>{
  mapData.accessTotal = count
  Object.keys(data).forEach(item=>{
    let index = chinaData.findIndex(i=>i.name === item)
    if(index>=0){
      chinaData[index].value = data[item].count
      chinaData[index].percent = (data[item].count / count * 100).toFixed(2)
    }
  })
  Object.keys(country_data).forEach(item=>{
    let index = worldData.findIndex(i=>i.name === item)
    if(index>=0){
      worldData[index].value = country_data[item].count
      worldData[index].percent = (country_data[item].count / count * 100).toFixed(2)
    }
  })
  option.visualMap.max = count
  option.series[0].data = chinaData
  resetMap()
}

defineExpose({
  chartResize,
  chartOption
})
</script>

<style lang="less" scoped>
.map-plugin-container{
  .map-container {
    width: 100%;
    .map-header{
      display: flex;
      justify-content: space-between;
      align-items: center;
      h3{
        span{
          font-size: 18px;
        }
        .province{
          color: rgb(156,148,127);
        }
        .country{
          color: rgb(62,102,216);
        }
      }
      .el-button{
        width: 120px;
        height: 32px;
      }
    }
    .map-content{
      min-height: 400px;
      .map-msg-list {
        margin-top: 20px;
        .map-msg-item {
          width: 100%;
          max-width: 270px;
          height: 40px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          font-weight: 600;
          color: #242F57;
          .map-msg-name{
            min-width: 100px;
          }
          .map-msg-percent{
            text-align: left;
            min-width: 65px;
            font-size: 14px;
          }
          .map-msg-count{
            text-align: right;
            font-size: 14px;
          }
        }
      }
    }
  }
}
</style>
